"""
https://github.com/offu/WeRoBot/issues/486
腾讯的限制
[BUG] handle里面函数处理超过5秒会连续调用3次
"""

import werobot
import datetime
import sys
import os
import time
from redis_interface import text_gen
import redis

sys.path.insert(0, '/home/peiyp/code')
from PyCmpltrtok.common import sep, to_decode, to_int

# 连接本机环境变量R_PORT指明的端口上的redis的第0个数据库
rdbr = redis.Redis('127.0.0.1', int(os.environ['R_PORT']), 0)
rdbr.get('try_it')

robot = werobot.WeRoBot(token='kx8M7eODU4HiyAmw3a')
robot.config['APP_ID'] = 'wx47577a029b258f6b'
robot.config['ENCODING_AES_KEY'] = 'LjBrnwSvqGXx89Tszleo4sMYp8yMALcTArwhPjxoZGJ'
client = robot.client

CHAR_LIMIT = 450
PROMPT = '（因平台限制，内容未完全展示，输入句号（.或。）来继续展示。）'
GO_ON_SET = set(['.', '。'])

if 0:
    """
    自定义菜单 需要 微信认证
    微信认证： 账号主体为个人，无法开通微信认证
    """
    PROMPT = '（因平台限制，内容未完全展示，按菜单按钮“继续”来继续展示。）'
    client.create_menu({
        'button': [{
            'type': 'click',
            'name': '继续',
            'key': 'go_on'
        }]
    })


    @robot.key_click('go_on')
    def go_on(message):    
        xtype = message.type
        print(datetime.datetime.now(), xtype)
        
        xuserid = message.source
        print('userid:', type(xuserid), xuserid)
        
        xoffset = rdbr.hget('username2offset', xuserid)
        xoffset = to_int(xoffset)
        xres = rdbr.hget('username2dynamic', xuserid)
        xres = to_decode(xres)
        xres = xres[xoffset:]
        print('output:', xres)
        return xres
    

@robot.handler
def hello(message):
    
    sep()
    
    # 判断类型
    xtype = message.type
    print(datetime.datetime.now(), xtype)
    if 'text' != xtype:
        return '目前仅支持文本信息！'
    
    # 用户标识
    xuserid = message.source
    print('userid:', type(xuserid), xuserid)
    
    # 输入文本
    xinput = message.content.strip()
    print('input:', xinput)
    
    def get_result():
        """
        闭包函数，拿数据
        """
        # 最后结果
        xoutput = rdbr.hget('username2output', xuserid)
        
        # 当前偏移
        xoffset = rdbr.hget('username2offset', xuserid)
        xoffset = to_int(xoffset)
        xoffset_ = xoffset
        # 分推理结束和未结束两种
        if xoutput is not None:  # 结束
            xoutput = xoutput.decode('utf8')
            
            # 取本次输出
            xoutput = xoutput[xoffset:]
            xlen_output = len(xoutput)
            
            # 分输出完成未完成两种
            if xlen_output <= CHAR_LIMIT:
                # 输出完成，清理username2dynamic以标志输出完成
                rdbr.hdel('username2dynamic', xuserid)
                rdbr.hdel('username2offset', xuserid)
                return xoutput
            else:
                # 输出未完成，分段输出
                xres = xoutput[:CHAR_LIMIT]
                
        else:  # 未结束
            
            # 从动态响应里拿
            xres = rdbr.hget('username2dynamic', xuserid)
            xres = to_decode(xres)
            
            # 限制一下长度
            xres = xres[xoffset:xoffset+CHAR_LIMIT]
            
        print('output:', xres)
        # 记录偏移
        xlen = len(xres)
        rdbr.hset('username2offset', xuserid, xoffset_ + xlen)
        
        return xres + PROMPT
    
    if xinput in GO_ON_SET:  # "继续显示"
        # 从动态响应里拿
        xres = rdbr.hget('username2dynamic', xuserid)
        # 没有动态响应，说明输出结束
        if xres is None:
            return '（已经没有需要继续输出的内容了。）'
        
        print('GO ON >>>>')
        return get_result()
    
    # 生成
    text_gen(rdbr, xinput, xuserid)
    
    # 既然限制5秒，干脆等3.75秒，让大模型去生成
    time.sleep(3.75)
    
    # 3.75秒后，拿结果
    xres = get_result()
    return xres


# 让服务器监听在 0.0.0.0:80
robot.config['HOST'] = '0.0.0.0'
robot.config['PORT'] = 80
robot.run()
